package com.yichang.comisiones.security;

import com.yichang.comisiones.dto.UsuarioDTO;
import com.yichang.comisiones.service.UsuarioService;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

/**
 * A custom service for retrieving users from a custom datasource, such as a
 * database. <p> This custom service must implement Spring's {@link UserDetailsService}
 */
@Component("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    protected static Logger logger = Logger.getLogger("service");
    @Autowired
    private UsuarioService usuarioService;

    /**
     * Retrieves a user record containing the user's credentials and access.
     */
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {

        // Declare a null Spring User
        UserDetails user = null;

        try {

            // Search database for a user that matches the specified username
            // You can provide a custom DAO to access your persistence layer
            // Or use JDBC to access your database
            // DbUser is our custom domain user. This is not the same as Spring's User
            List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
            UsuarioDTO usuario = usuarioService.buscarPorCodigo(username);            
            if (usuario == null) {
                usuario = usuarioService.buscarPorCorreo(username);
                if (usuario == null) {
                    throw new Exception("No existe el usuario");
                }
                authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
            }
            if (usuario.getActive().booleanValue() == false) {
                throw new Exception("Usuario no activo");
            }

            //Dando acceso a nivel usuario al sistema.            
            logger.debug("Grant ROLE_USER to this user");
            authList.add(new GrantedAuthorityImpl("ROLE_USER"));

            // Populate the Spring User object with details from the dbUser
            // Here we just pass the username, password, and access level
            // getAuthorities() will translate the access level to the correct role type
            
            String idEmpleado = null;
            if (usuario.getEmpleado() != null){
                idEmpleado = usuario.getEmpleado().getIdEmpleado();
            }
            
            user = new CustomUser(
                    idEmpleado,
                    usuario.getEmpleado().getNombreCompleto() == null ? usuario.getCorreo() : usuario.getEmpleado().getNombreCompleto(),
                    usuario.getPassword().toLowerCase(),
                    true,
                    true,
                    true,
                    true,
                    authList);

        } catch (Exception e) {
            logger.error(e);
            throw new UsernameNotFoundException(e.getMessage());
        }

        // Return user to Spring for processing.
        // Take note we're not the one evaluating whether this user is authenticated or valid
        // We just merely retrieve a user that matches the specified username
        return user;
    }
}